package cn.hacynn.nd.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @Author Hacynn
 * @Date 2024/5/28 0:02
 * @Version 1.0
 * 将 redis 模板对象 RedisTemplate 注入到 Bean 中，并修改 redis 的内容序列化器
 */
@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean   // 项目启动时让方法能够被调用并创建对象
    // 配置类要使用依赖注入时, 直接写在参数即可, 注入 redis 连接工厂对象 RedisConnectionFactory
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {   // RedisTemplate: redis模板对象
        log.info("开始创建 redis 模板对象...");
        RedisTemplate template = new RedisTemplate();
        // 设置 redis 的连接工厂对象
        template.setConnectionFactory(redisConnectionFactory);
        // 定义Jackson2JsonRedisSerializer序列化对象
        Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型，类必须是非final修饰的，final修饰的类，比如String,Integer等会报异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        StringRedisSerializer stringSerial = new StringRedisSerializer();
        // redis key 序列化方式使用stringSerial
        template.setKeySerializer(stringSerial);
        // redis value 序列化方式使用jackson
        template.setValueSerializer(stringSerial);
        // redis hash key 序列化方式使用stringSerial
        template.setHashKeySerializer(stringSerial);
        // redis hash value 序列化方式使用jackson
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        template.setEnableTransactionSupport(true);
        return template;
    }
}
